<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
</html>
<script>
   // 在 Javascript 中，函数是第一类对象。头等函数意味着该语言中的函数被视为任何其他变量。
   // 一个函数可以作为参数传递给其他函数，可以由另一个函数返回，也可以作为一个值分配给一个变量。
   // 例如，在下面的示例中，分配给侦听器的处理函数
   const handler = () => console.log ('This is a click handler function');
    document.addEventListener ('click', handler);

    // 什么是一阶函数？
    // 一阶函数是不接受另一个函数作为参数并且不返回函数作为其返回值的函数。
    const firstOrder = () => console.log ('I am a first order function!');
    firstOrder()

    // 什么使高阶函数  
    //高阶函数就是可以把函数作为参数 和返回值的函数 
    // 比如闭包 ECMAScript中也提供大量的高级函数如forEach(), every(), some(), reduce()等等。    
    // 对应到数组中的高阶函数 
        //map 
        //参数 接收两个参数 一个回调函数 一个事回调函数的this值(可选)
        //回调函数 被默认传入3个值   1参当前元素i 当前下标 整个数组 
        //对原数组没得影响  如下  
        let nums = [1,2,3];
        let obj = {val:5};
        let newNums = nums.map(function(item,index,array){
            return item+index+array[index] + this.val;
                //对第一个元素，1 + 0 + 1 + 5 = 7
                //对第二个元素，2 + 1 + 2 + 5 = 10
                //对第三个元素，3 + 2 + 3 + 5 = 13
        },obj);  
        //当然 后面的参数 都时可选的 不用的话 可以省略的
        //reduce  filter  sort 都是


     //函数柯里化 
     //柯里化是将具有多个参数的函数转换为每个只有一个参数的函数序列的过程。
     //Currying 以数学家Haskell Curry 的名字命名。通过应用柯里化，n 元函数将其变成一元函数。

     // 让我们举一个 n-ary 函数的例子，以及它如何变成一个柯里化函数    
    const multiArgFunction = (a, b, c) => a + b + c;
    console.log(multiArgFunction(1,2,3));// 6
    const curryUnaryFunction = a => b => c => a + b + c;
    curryUnaryFunction (1);             // return a function: b => c =>  1 + b + c
    curryUnaryFunction (1) (2);         // return a function: c => 3 + c
    curryUnaryFunction (1) (2) (3);     // return 数字 6
    //Curried 函数对于提高代码复用性和函数组合非常有用。

</script>